package com.yulan.bankback.service.admin.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yulan.bankback.entity.dto.bank.PieChartDto;
import com.yulan.bankback.entity.model.admin.AbnormalUser;
import com.yulan.bankback.entity.model.admin.EverydayAccountAbnormal;
import com.yulan.bankback.entity.model.admin.RemoteLoginFreq;
import com.yulan.bankback.entity.vo.AbnormalUserVo;
import com.yulan.bankback.mapper.admin.AbnormalUserMapper;
import com.yulan.bankback.mapper.admin.EverydayAccountAbnormalMapper;
import com.yulan.bankback.mapper.admin.RemoteLoginFreqMapper;
import com.yulan.bankback.service.admin.AbnormalService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class AbnormalServiceImpl implements AbnormalService {

    @Resource
    private RemoteLoginFreqMapper loginFreqMapper;

    @Resource
    private AbnormalUserMapper abnormalUserMapper;

    @Resource
    private EverydayAccountAbnormalMapper everydayAccountAbnormalMapper;


    private static final SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private static final SimpleDateFormat formatter2 = new SimpleDateFormat("yyyy-MM-dd");

    private static final SimpleDateFormat formatter3 = new SimpleDateFormat("MM-dd");


    @Override
    public AbnormalUserVo getAbnormalUserVo(String interval) {
        AbnormalUserVo vo = new AbnormalUserVo();
        List<RemoteLoginFreq> remoteLoginFreqs = loginFreqMapper.getRemoteLoginFreqInterval(interval);

        List<String> remoteLoginDate = remoteLoginFreqs.stream()
                .map(item ->formatter3.format(item.getTime()))
                .collect(Collectors.toList());
        List<Integer> remoteLoginData = remoteLoginFreqs.stream()
                .map(RemoteLoginFreq::getCount)
                .collect(Collectors.toList());

        List<EverydayAccountAbnormal> accountAbnormals = everydayAccountAbnormalMapper.getAbnormalINterval(interval);

        List<String> accountAbnormalDate = accountAbnormals.stream()
                .map(item -> formatter3.format(item.getTime()))
                .collect(Collectors.toList());

        List<Integer> accountAbnormalData = accountAbnormals.stream()
                .map(EverydayAccountAbnormal::getCount)
                .collect(Collectors.toList());

        while (remoteLoginDate.size() > 10) remoteLoginDate = changeListSize(remoteLoginDate, 4);
        while (remoteLoginData.size() > 10) remoteLoginData = changeListSize(remoteLoginData, 4);
        while (accountAbnormalDate.size() > 10) accountAbnormalDate = changeListSize(accountAbnormalDate, 4);
        while (accountAbnormalData.size() > 10) accountAbnormalData = changeListSize(accountAbnormalData, 4);

        vo.setRemoteLoginDate(remoteLoginDate);
        vo.setRemoteLoginData(remoteLoginData);
        vo.setAbnormalDate(accountAbnormalDate);
        vo.setAbnormalData(accountAbnormalData);


        List<PieChartDto<Integer>> abnormalRegion = new ArrayList<>();
        Map<String, Integer> regionMap = new HashMap<>();
        List<AbnormalUser> abnormalUsers = abnormalUserMapper.selectList(new QueryWrapper<>());
        abnormalUsers.forEach(item ->{
            regionMap.put(item.getType(), regionMap.getOrDefault(item.getType(), 0) + 1);
        });

        for(String type : regionMap.keySet()){
            abnormalRegion.add(new PieChartDto<Integer>(regionMap.get(type), type));
        }
        vo.setAbnormalTypes(abnormalRegion);

        return vo;
    }

    @Override
    public List<AbnormalUser> getAllAbnormalUser() {
        List<AbnormalUser> abnormalUsers = abnormalUserMapper.selectList(
                new QueryWrapper<AbnormalUser>().last("limit 500"));
        abnormalUsers.forEach(item -> item.setViewTime(formatter.format(item.getCreateTime())));
        return abnormalUsers;
    }

    @Override
    public List<AbnormalUser> getAbnormalUserConditions(String start, String end,
                                                        String type, String username,
                                                        String uid, String ip) {
        QueryWrapper<AbnormalUser> queryWrapper = new QueryWrapper<>();
        if(StringUtils.isNotBlank(start)) queryWrapper.gt("create_time", DateUtil.parseDate(start));
        if(StringUtils.isNotBlank(end)) queryWrapper.lt("create_time", DateUtil.parseDate(end));
        if(StringUtils.isNotBlank(type)) queryWrapper.eq("type", type);
        if(StringUtils.isNotBlank(username)) queryWrapper.eq("username", username);
        if(StringUtils.isNotBlank(uid)) queryWrapper.eq("uid", uid);
        if(StringUtils.isNotBlank(ip)) queryWrapper.eq("ip", ip);

        List<AbnormalUser> res = abnormalUserMapper.selectList(queryWrapper);
        res.forEach(item -> item.setViewTime(formatter.format(item.getCreateTime())));
        return res;
    }

    private <T> List<T> changeListSize(List<T> list, int mod){
        T first = list.get(0);
        T last = list.get(list.size() - 1);

        List<T> res = new ArrayList<>();
        res.add(first);
        for(int i = 1; i < list.size() - 1; i++){
            if(i % mod != 0)
                res.add(list.get(i));
        }
        res.add(last);
        return res;
    }
}
